package com.will.network.images;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.view.ViewGroup;
import android.widget.ImageView;

import com.android.volley.toolbox.ImageLoader;

import com.will.network.RequestManager;

/**
 * Implementation of volley's ImageCache interface. This manager tracks the application image loader and cache. 
 * 
 * Volley recommends an L1 non-blocking cache which is the default MEMORY CacheType. 
 * @author Will
 *
 */
public class ImageCacheManager{

	
	private static ImageCacheManager mInstance;
	
	/**
	 * Volley image loader
	 */
	private ImageLoader mImageLoader;
    private ImageLoader mL2ImageLoader;

	/**
	 * Image cache implementation
	 */
    private ImageLruMemoryCache mImageCache;
	private ImageL2Cache mL2ImageCache;

	
	/**
	 * @return
	 * 		instance of the cache manager
	 */
	public static ImageCacheManager getInstance(){
		if(mInstance == null)
			mInstance = new ImageCacheManager();
		
		return mInstance;
	}

	
	/**
	 * Initializer for the manager. Must be called prior to use. 
	 * 
	 * @param context
	 * 			application context
	 * @param uniqueName
	 * 			name for the cache location
	 * @param memCacheSize
	 * 			max size for the memory cache
     * @param diskCacheSize
     *          max size for the disk cache
	 * @param compressFormat
	 * 			file type compression format.
	 * @param quality
	 */
    private Context mContext;
    private String uniqueName;
    private int memCacheSize;
    private int diskCacheSize;
    private CompressFormat compressFormat;
    private int quality;
	public void init(Context context, String uniqueName, int memCacheSize, int diskCacheSize, CompressFormat compressFormat, int quality){
        mContext = context;
        this.uniqueName = uniqueName;
        this.memCacheSize = memCacheSize;
        this.diskCacheSize = diskCacheSize;
        this.compressFormat = compressFormat;
        this.quality = quality;

//        mImageCache = new ImageLruMemoryCache(memCacheSize);
//        mImageLoader = new ImageLoader(RequestManager.getInstance().getRequestQueue(),  mImageCache);
//
//        mL2ImageCache = new ImageL2Cache(context, mImageCache, uniqueName, diskCacheSize, compressFormat, quality);
//        mL2ImageLoader = new ImageLoader(RequestManager.getInstance().getRequestQueue(), mL2ImageCache);
    }

    private ImageLruMemoryCache getImageCache(){
        if (mImageCache == null)
            mImageCache = new ImageLruMemoryCache(memCacheSize);
        return mImageCache;
    }

    private ImageL2Cache getImageL2Cache(){
        if (mL2ImageCache == null)
            mL2ImageCache = new ImageL2Cache(mContext, getImageCache(), uniqueName, diskCacheSize, compressFormat, quality);
        return mL2ImageCache;
    }

    /**
     * @return
     * 		instance of the image loader
     */
    public ImageLoader getImageLoader() {
        if (mImageLoader == null) {
            mImageLoader = new ImageLoader(RequestManager.getInstance().getRequestQueue(), getImageCache());
        }
        return mImageLoader;
    }

    public ImageLoader getL2ImageLoader() {

        if (mL2ImageLoader == null)
            mL2ImageLoader = new ImageLoader(RequestManager.getInstance().getRequestQueue(), getImageL2Cache());

        return mL2ImageLoader;
    }

    public void clearDiskCache(){
        if (mL2ImageCache != null){
            mL2ImageCache.clearDiskCache();
        }
    }
    public void clearMemoryCache(){
        if(mImageCache != null){
            mImageCache.evictAll();
        }
    }












    /** ******************************************************************************
     * 独立于imageLoader的 bitmap cache manager.
     */

	public Bitmap getBitmap(String url) {
        return getBitmap(url, null);
	}
	public void putBitmap(String url, Bitmap bitmap) {
        putBitmap(url, bitmap, null);
	}

    public Bitmap getL2Bitmap(String url) {
        return getL2Bitmap(url, null);
    }

    public void putL2Bitmap(String url, Bitmap bitmap) {
        putL2Bitmap(url, bitmap, null);
    }

    public Bitmap getBitmap(String url, ImageView imageView) {
        String key = getCacheKey(url, imageView);
        try {
            return getImageCache().getBitmap(key);
        } catch (NullPointerException e) {
            throw new NullPointerException("Cache Not initialized");
        }
    }

    public void putBitmap(String url, Bitmap bitmap, ImageView imageView) {
        String key = getCacheKey(url, imageView);
        try {
            getImageCache().putBitmap(key, bitmap);
        } catch (NullPointerException e) {
            throw new NullPointerException("Cache Not initialized");
        }
    }

    public Bitmap getL2Bitmap(String url, ImageView imageView) {
        String key = getCacheKey(url, imageView);
        try {
            return getImageL2Cache().getBitmap(key);
        } catch (NullPointerException e) {
            throw new NullPointerException("Cache Not initialized");
        }
    }

    public void putL2Bitmap(String url, Bitmap bitmap, ImageView imageView) {
        String key = getCacheKey(url, imageView);
        try {
            getImageL2Cache().putBitmap(key, bitmap);
        } catch (NullPointerException e) {
            throw new NullPointerException("Cache Not initialized");
        }
    }
    /***
     * Create key from Volley ImageLoader. In order to hit from volley image cache.
     * @param url
     * @param imageView
     * @return key
     */
    public static String getCacheKey(String url, ImageView imageView) {
        int maxWidth = 0, maxHeight = 0;
        ImageView.ScaleType scaleType = ImageView.ScaleType.FIT_CENTER;
        if (imageView != null){
            int width = imageView.getWidth();
            int height = imageView.getHeight();
            scaleType = imageView.getScaleType();

            boolean wrapWidth = false, wrapHeight = false;
            if (imageView.getLayoutParams() != null) {
                wrapWidth = imageView.getLayoutParams().width == ViewGroup.LayoutParams.WRAP_CONTENT;
                wrapHeight = imageView.getLayoutParams().height == ViewGroup.LayoutParams.WRAP_CONTENT;
            }

            // if the view's bounds aren't known yet, and this is not a wrap-content/wrap-content
            // view, hold off on loading the image.
            boolean isFullyWrapContent = wrapWidth && wrapHeight;
            if (width == 0 && height == 0 && !isFullyWrapContent) {
                return null;
            }

            // Calculate the max image width / height to use while ignoring WRAP_CONTENT dimens.
            maxWidth = wrapWidth ? 0 : width;
            maxHeight = wrapHeight ? 0 : height;
        }
        return ImageLoader.getCacheKey(url, maxWidth, maxHeight, scaleType);
    }


    /**
     * @deprecated use {@link will.utils.network.images.round.RoundImageView} instead.
     * It's a compatible method
     * @return
     */
    @Deprecated
    public ImageLoader getRoundImageLoader(){
        return getImageLoader();
    }
}

